package com.maolong.spring.beans.factory.support.annotation;

import com.maolong.spring.beans.BeansException;
import com.maolong.spring.beans.PropertyValue;
import com.maolong.spring.beans.PropertyValues;
import com.maolong.spring.beans.factory.annotation.Autowired;
import com.maolong.spring.beans.factory.annotation.Bean;
import com.maolong.spring.beans.factory.annotation.ComponentScan;
import com.maolong.spring.beans.factory.config.BeanDefinition;
import com.maolong.spring.beans.factory.support.AbstractBeanDefinitionReader;
import com.maolong.spring.beans.factory.support.BeanDefinitionRegistry;
import com.maolong.spring.core.io.Resource;
import com.maolong.spring.core.io.ResourceLoader;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;

public class AnnotationBeanDefinitionReader extends AbstractBeanDefinitionReader {

    public  AnnotationBeanDefinitionReader(BeanDefinitionRegistry registry) {
        super(registry);
    }

    public  AnnotationBeanDefinitionReader(BeanDefinitionRegistry registry, ResourceLoader resourceLoader) {
        super(registry, resourceLoader);
    }
    @Override
    public void loadBeanDefinitions(Class aclass) {
        Annotation[] annotations = aclass.getAnnotations();
        String basePackages;
        for ( Annotation annotation : annotations){
            if (annotation instanceof ComponentScan){
                basePackages = ((ComponentScan) annotation).value();
            }
        }
        basePackages = aclass.getPackage().getName();
        scanAndRegisterBeanDefinitions(basePackages);
    }

    private void scanAndRegisterBeanDefinitions(String basePackages) {
        String locationPath = basePackages.replace(".", "/");
        Resource[] resources = getResourceLoader().getResources(locationPath);
        for (Resource resource : resources){
            registerBeanDefinitions(resource);
        }
    }

    private void registerBeanDefinitions(Resource resource) {
        // 获取类文件名称（如 "User.class"）
        String filename = resource.getFileName();
        if (filename != null && filename.endsWith(".class")) {
            // 将路径转换为类名：例如 "com/maolong/spring/beans/User.class" -> "com.maolong.spring.beans.User"
            String className = filename.substring(0, filename.length() - 6); // 去掉 ".class"
            className = className.replace("/", ".");
            try {
                Class<?> aClass = Class.forName(className);
                // 创建 BeanDefinition
                BeanDefinition beanDefinition = new BeanDefinition(aClass, new PropertyValues());
                // 处理字段注入 @Autowired
                Field[] declaredFields = aClass.getDeclaredFields();
                for (Field field : declaredFields) {
                    if (field.isAnnotationPresent(Autowired.class)) {
                        // 添加字段注入信息（name 可用于后续依赖解析）
                        // todo 这里以后需要扩展根据类型去获取
                        beanDefinition.getPropertyValues().addPropertyValue(
                                new PropertyValue(field.getName(), field.getType())
                        );
                    }
                }
                // 注册 BeanDefinition
                getRegistry().registerBeanDefinition(aClass.getSimpleName(), beanDefinition);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException("类加载失败: " + className, e);
            }
        }
    }


    @Override
    public void loadBeanDefinitions(Resource resource) throws BeansException {
        try {
            InputStream inputStream = resource.getInputStream();
             doLoadBeanDefinitions(inputStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private void doLoadBeanDefinitions(InputStream inputStream) {
    }

    @Override
    public void loadBeanDefinitions(Resource... resources) throws BeansException {
        for ( Resource resource : resources){
             loadBeanDefinitions(resource);
        }
    }

    @Override
    public void loadBeanDefinitions(String location) throws BeansException {
        Resource resource = getResourceLoader().getResource(location);
         loadBeanDefinitions(resource);
    }

    @Override
    public void loadBeanDefinitions(String... locations) throws BeansException {
        for (String location : locations){
            loadBeanDefinitions( location);
        }
    }
}
